﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Generic.CodePlex;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        private static string chars = "eeeeeeeeeeeeaaaaaaaaaiiiiiiiiioooooooonnnnnnrrrrrrttttttllllssssuuuuddddgggbbccmmppffhhvvwwyykjxqz              ";
        private static Random rand = new Random();
        private static int items = 500000;

        static void Main(string[] args)
        {
            CircularList<string> list1 = new CircularList<string>(items);
            List<string> list2 = new List<string>(items);
            LinkedList<string> list3 = new LinkedList<string>();

            string[] phrases = new string[items];
            for (int i = 0; i < phrases.Length; i++)
            {
                phrases[i] = RandString();
            }


            TimeSpan list1Time, list2Time, list3Time;


            list1.SetReadLocked(true);
            list1Time = TimeSpan.FromTicks(AddStrings(phrases, list1));
            list1.SetReadLocked(false);
            list2Time = TimeSpan.FromTicks(AddStrings(phrases, list2));
            list3Time = TimeSpan.FromTicks(AddStrings(phrases, list3));
            Console.WriteLine("Add times");
            Console.WriteLine("CircularList " + list1Time.ToString());
            Console.WriteLine("List         " + list2Time.ToString());
            Console.WriteLine("LinkedList   " + list3Time.ToString());

            list1Time = ParallelCountChars(list1);
            list2Time = ParallelCountChars(list2);
            list3Time = ParallelCountChars(list3);

            Console.WriteLine("Parallel times");
            Console.WriteLine("CircularList " + list1Time.ToString());
            Console.WriteLine("List         " + list2Time.ToString());
            Console.WriteLine("LinkedList   " + list3Time.ToString());

            Console.ReadLine();
        }

        private static long AddStrings(string[] phrases, ICollection<string> list)
        {
            long listTime = 0;
            for (int i = 0; i < 3; i++)
            {
                list.Clear();
                long startTime = DateTime.Now.Ticks;
                foreach (string phrase in phrases)
                {
                    list.Add(phrase);
                }
                listTime += (DateTime.Now.Ticks - startTime);
            }
            return listTime / 3;
        }

        private static TimeSpan ParallelCountChars(IEnumerable<string> list)
        {
            long listTime = 0;
            for (int i = 0; i < 3; i++)
            {
                long startTime = DateTime.Now.Ticks;
                bool containsSmurf = false;
                Parallel.ForEach(list, item =>
                    {
                        containsSmurf |= item.Contains("smurf");
                    });
                containsSmurf = !containsSmurf;
                listTime += (DateTime.Now.Ticks - startTime);
            }
            return TimeSpan.FromTicks(listTime / 3L);
        }

        

        static string RandString()
        {
            int stringLength = rand.Next(24) + 7;
            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 0; i <= stringLength; i++)
            {
                stringBuilder.Append(chars[rand.Next(chars.Length-1)]);
            }

            return stringBuilder.ToString();
        }
    }
}
